home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 30
/
Amiga Format AFCD30 (Sep 1998, Issue 114).iso
/
-seriously_amiga-
/
workbench
/
-datatypes-
/
mpegsystem
/
classbase.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-18
|
16KB
|
500 lines
/*
**
** $VER: classbase.c 1.5 (1.6.98)
** mpegsystem.datatype 1.5
**
** Library routines for a DataTypes class
**
** Written 1997/1998 by Roland 'Gizzy' Mainz
** Original example source from David N. Junod
**
*/
/* main includes */
#include "classbase.h"
/****** mpegsystem.datatype/MAIN *********************************************
*
* INTRODUCTION
* Datatypes class for MPEG 1 System movies (including VideCD streams)
*
* REQUIREMENTS
* - You need at least Kick/WB 3.0.
*
* - datatypes.library >= V45
*
* - "datatypes/animation.datatype", >= V40.
* "animation.datatype 40.6 (28.09.93)" requires itself some
* libraries/boopsi classes:
* - "realtime.library", >= V39 - for timing
* - "gadgets/tapedeck.gadget" (any version) - for the controls
*
* - mpegvideo.datatype >= V1.6 (V2.x preferred)
*
* - mpegaudio.datatype >= V1.1
*
* USAGE
* If the datatypes descriptor file was activated, any attempt to load
* a MPEG System stream using GMultiView, MultiView, AmigaGuide or
* SwitchWindow will load and play the movie.
*
* INSTALLATION
* After unpacking this archive:
* Because this version does not include an Installer script, you have
* to do the installation manually through the shell:
*
* - Unpack this archive and copy the "mpegsystem.datatype" to
* SYS:Classes/DataTypes/:
*
* Copy CLONE FROM "mpegsystem.datatype" TO
* "SYS:Classes/DataTypes/mpegsystem.datatype"
*
* - Then copy the datatypes descriptor into the DEVS:DataTypes
* directory.
* If the descriptor already exists, you should not replace it,
* otherwise you may loose "toolnodes" and other settings stored in
* the existing descriptor.
*
* Copy CLONE FROM "MPEG System(%|.info)" TO DEVS:Datatypes/
*
* SOURCE
* Source is included as an example how to write a datatypes clas
* implements a virtual filesystem and embeds other datatype objects
* for it's work.
*
* MODEL
* This datatype uses a very complex model for decoding MPEG system
* streams. The small drawing below shows the model (OK, the
* drawing is not very good, it's incomplete and so on. If someone
* has the time to draw a better one, send it to me).
*
* system stream
* |
* |
* Y
* +-------------------------------------------------------------+
* | mpeg system datatype |
* +-----------------------------------------+-------------------+
* | demultiplexer | ADTM_LOADFRAME |
* | video 0...video n | audio 0... audio n | ADTM_UNLOADFRAME |
* +-----+-------+------+------+-------+-----+-------------------+
* | | | | ^ ^
* | | | | | |
* | * | * | |
* | | | |
* | | | |
* Y Y | |
* +---------------------+ +---------------------+ | |
* | mpeg video datatype | | mpeg audio datatype | | |
* +-----------+---------+ +--------+------------+ | |
* | | | |
* | | | |
* | +-----------------------+ |
* +------------------------------------------------+
*
* AUTHOR
* If you want to blame me, report any bugs, or wants a new version
* send your letter to:
* Roland Mainz
* Hohenstaufenstraße 8
* 52388 Nörvenich
* GERMANY
*
* Phone: (+49)(0)2426/901568
* Fax: (+49)(0)2426/901569
*
* EMAIL is also available (if you want to send me attachments
* larger than 1MB (up to 5MB, more with my permission):
*
* GISBURN@w-specht.rhein-ruhr.de
*
* Up to August 1998 I'm reachable using this email address, too:
* Reinhold.A.Mainz@KBV.DE
*
* | Please put your name and address in your mails !
* | German mailers should add their phone numbers.
* | See BUGS section above when submitting bug reports.
*
* Sorry, but I can only look once a week for mails.
* If you don't hear something from me within three weeks, please
* send your mail again (but watch about new releases) (problems with
* this email port are caused by reconfigurations, hackers, network
* problems etc.).
*
* The entire "mpegsystem.datatype" package may be noncommercially
* redistributed, provided that the package is always distributed
* in it's complete form (including it's documentation). A small
* copy fee for media costs is okay but any kind of commercial
* distribution is strictly forbidden without my permission !
* Comments and suggestions how to improve this program are
* generally appreciated!
*
* Thanks to David Junod, who wrote the animation.datatype and lots of
* the datatypes example code, Matt Dillon for his DICE,
* Olaf 'Olsen' Barthel for his help, ideas and some text clips from
* his documentations.
*
******************************************************************************
*
*/
/****** mpegsystem.datatype/--datasheed-- ************************************
*
* NAME
* mpegsystem.datatype -- data type for MPEG System streams
*
* SUPERCLASS
* animation.datatype
*
* DESCRIPTION
* The anim datatype, a sub-class of the animation.datatype, is used to
* load and play MPEG System movies.
*
* METHODS
* OM_NEW -- Create a new animation object from a description file. The
* source may only be a file.
*
* OM_DISPOSE -- Dispose instance and contents (embedded objects etc.
* etc.), then pass msg to superclass
*
* OM_UPDATE -- Perform an ICM_CHECKLOOP check, and if succesfull, the
* method will be executed like OM_SET downstairs.
*
* OM_SET -- Pass msg to superclass and call GM_RENDER if retval from
* superclass was != 0UL.
*
* DTM_WRITE -- Save object's contents in local (MPEG System) or
* superclass (IFF ILBM) format.
* NOT IMPLEMENTED YET
*
* ADTM_LOADFRAME -- Fill in struct adtFrame with requested information
* from embedded objects like bitmap, colormap and sample.
*
* ADTM_UNLOADFRAME -- Free resources obtained by ADTM_UNLOADFRAME.
* The method is passed to the embedded objects.
*
* All other methods are passed unchanged to superclass.
*
* ATTRIBUTES
* Following attributes are set by the object and are READ-ONLY for
* applications:
*
* BUGS
* - Support for streams with multiple video- and/or audio-streams
* has been removed. The datatype uses currently evertimes
* the first video- and the first audio-stream it finds.
*
* - ADTM_START, ADT_PAUSE, ADTM_STOP and ADTM_LOCATE are not passed
* to the embedded mpevideo.datatype object(s), which may cause
* speed loss if this datatype does speed optimisations based on use
* of those methods.
*
* - The sound may be out-of-sync in the case that a stream
* is very long (more than 60 minutes) due rounding problems.
* (In theory it should not occur - and I did not see the bug...).
*
* TODO
* - Fixing the bugs above.
*
* - Write the "--input_format--"-Autodoc section.
*
* - Leading zeros in the beginning of the file except the "start code"
* begin sequence causes a stream not to be recognized by
* datatypes.library.
* May happen if someone reads raw data from a VideoCD.
*
* - Writing the encoder part, using mpegvideo.datatype V2's encoder
* and mpegaudio.datatype's encoder parts.
*
* Coming soon... :-)
*
* - Implementation of ACTION_INFO in the internal filesystem that
* (in theory) optimized reading using async I/O gets correct
* parameters.
*
* - Support for MPEG 2 system streams.
*
* - QUICKSCAN option for optimized and much faster scanning of system
* streams.
*
* HISTORY
* V1.1
* First public release.
*
* V1.2
* - Fixed the descriptor (e.g. the file "MPEG System"). The
* old one contains unneccesary data in the comparisation mask.
* Now the descriptor matches the standard, except that
* leading zero bytes (0x00) causes that the stream won't be
* identified.
* Thanks to Steve Cutting (stevejc@c031aone.net.au) for reporting
* the bug.
* Fixed.
*
* - Implemented IGNOREERRORS switch to get Steve Cutting's
* (stevejc@c031aone.net.au) example file
* "http://www.utexas.edustudents/cjso/Chabad/video/chase.mpg"
* working.
*
* - Added missing VERBOSESYNTAX and DEBUG options to find problems
* in the datatype without recompiling the complete source.
*
* - Fixed a bug in the FS:
* The internal filesystem now returns ERROR_SEEK_ERROR of someone
* send an ACTION_SEEK with an unknown position mode
* (e.g. if it is none of OFFSET_(BEGINNING|CURRENT|END)).
* Fixed.
*
* - Fixed some problems with the VERBOSE and DEBUG output (missing
* newlines, single lines > 75 chars etc.).
* Fixed.
*
* V1.3
* - Minor code cleanup
*
* - Fixed and updated the autodoc.
*
* - Increased the handlers process priority up to 9
* (normal FFS tasks are running at priority 10) to get more speed
* during scanning.
*
* V1.4
* - Added asyncio.library support code (but it does not work yet...).
*
* - Implemented ACTION_COPY_DIR_FH to get DupLockFromFH working which
* is used in the new mpegaudio.datatype V2 (currently this feature
* is not used because of some problems with mpega.library, but...).
*
* - Fixed a bug in OM_NEWs state machine which caused big problems
* if an error occurs with IoErr() == 0.
* Fixed.
*
* V1.5
* - Removed non-working asyncio.library support code.
*
* - Implemented my own "async" dos packet system, which is more
* efficient than asyncio.library's one (in our case !).
*
* - Added/removed/moved some code to get rid of a "Seek" in the
* scan phase.
*
* - Added some usefull comments.
*
* - Moved preferences support code into "prefs.c".
*
* - Implemented NOVERBOSE option as requested by many people.
*
* - Increased handlers priority to 15 and renamed the hander's
* process.
*
* SEE ALSO
* animation.datatype,
* anim.datatype,
* gifanim.datatype,
* mpegvideo.datatype, mpegaudio.datatype,
* picmovie.datatype,
* cdxl.datatype, avi.datatype, quicktime.datatype,
* moviesetter.datatype,
* film.datatype,
* directory.datatype,
* markabletextdtclass
*
*******************************************************************************
*
*/
/****** mpegsystem.datatype/--input_format-- *********************************
*
* NAME
* MPEG System -- MPEG System stream format
*
* DESCRIPTION
* <Not written yet, sorry>
*
* SEE ALSO
*
*******************************************************************************
*
*/
/*****************************************************************************/
DISPATCHERFLAGS
struct IClass *ObtainMPEGSystemEngine( REGA6 struct ClassBase *cb )
{
return( (cb -> cb_Lib . cl_Class) );
}
/*****************************************************************************/
DISPATCHERFLAGS
struct Library *LibInit( REGD0 struct ClassBase *cb, REGA0 BPTR seglist, REGA6 struct ExecBase *sysbase )
{
cb -> cb_SegList = seglist;
cb -> cb_SysBase = sysbase;
InitSemaphore( (&(cb -> cb_Lock)) );
/* Kickstart V3.0 ? */
if( (cb -> cb_SysBase -> LibNode . lib_Version) >= 39UL )
{
/* Obtain ROM libs */
if( cb -> cb_UtilityBase = OpenLibrary( "utility.library", 39UL ) )
{
if( cb -> cb_DOSBase = OpenLibrary( "dos.library", 39UL ) )
{
if( cb -> cb_GfxBase = OpenLibrary( "graphics.library", 39UL ) )
{
if( cb -> cb_IntuitionBase = OpenLibrary( "intuition.library", 39UL ) )
{
return( (&(cb -> cb_Lib . cl_Lib)) );
#ifdef COMMENTED_OUT
CloseLibrary( (cb -> cb_IntuitionBase) );
#endif /* COMMENTED_OUT */
}
CloseLibrary( (cb -> cb_GfxBase) );
}
CloseLibrary( (cb -> cb_DOSBase) );
}
CloseLibrary( (cb -> cb_UtilityBase) );
}
}
return( NULL );
}
/*****************************************************************************/
DISPATCHERFLAGS
LONG LibOpen( REGA6 struct ClassBase *cb )
{
LONG retval = (LONG)cb;
BOOL success = TRUE;
ObtainSemaphore( (&(cb -> cb_Lock)) );
/* Use an internal use counter */
cb -> cb_Lib . cl_Lib . lib_OpenCnt++;
cb -> cb_Lib . cl_Lib . lib_Flags &= ~LIBF_DELEXP;
if( (cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 1U )
{
if( (cb -> cb_Lib . cl_Class) == NULL )
{
success = FALSE;
/* Only datatypes.library >= V45 supports virtual handlers... */
if( cb -> cb_DataTypesBase = OpenLibrary( "datatypes.library", 45UL ) )
{
/* Should require animation.datatype V41 */
if( cb -> cb_SuperClassBase = OpenLibrary( "datatypes/animation.datatype", 39UL /*41UL*/ ) )
{
if( cb -> cb_Lib . cl_Class = initClass( cb ) )
{
success = TRUE;
}
}
}
}
}
if( !success )
{
CloseLibrary( (cb -> cb_SuperClassBase) );
CloseLibrary( (cb -> cb_DataTypesBase) );
cb -> cb_DataTypesBase = cb -> cb_SuperClassBase = NULL;
(cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
retval = 0L;
}
ReleaseSemaphore( (&(cb -> cb_Lock)) );
return( retval );
}
/*****************************************************************************/
DISPATCHERFLAGS
LONG LibClose( REGA6 struct ClassBase *cb )
{
LONG retval = 0L;
ObtainSemaphore( (&(cb -> cb_Lock)) );
if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
{
(cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
}
if( ((cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 0U) && (cb -> cb_Lib . cl_Class) )
{
if( FreeClass( (cb -> cb_Lib . cl_Class) ) )
{
cb -> cb_Lib . cl_Class = NULL;
CloseLibrary( (cb -> cb_SuperClassBase) );
CloseLibrary( (cb -> cb_DataTypesBase) );
}
else
{
cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
}
}
ReleaseSemaphore( (&(cb -> cb_Lock)) );
if( (cb -> cb_Lib . cl_Lib . lib_Flags) & LIBF_DELEXP )
{
retval = LibExpunge( cb );
}
return( retval );
}
/*****************************************************************************/
DISPATCHERFLAGS
LONG LibExpunge( REGA6 struct ClassBase *cb )
{
BPTR seg;
if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
{
cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
seg = NULL;
}
else
{
Remove( (&(cb -> cb_Lib . cl_Lib . lib_Node)) );
seg = cb -> cb_SegList;
CloseLibrary( (cb -> cb_IntuitionBase) );
CloseLibrary( (cb -> cb_GfxBase) );
CloseLibrary( (cb -> cb_DOSBase) );
CloseLibrary( (cb -> cb_UtilityBase) );
FreeMem( (APTR)((ULONG)(cb) - (ULONG)(cb -> cb_Lib . cl_Lib . lib_NegSize)), (ULONG)((cb -> cb_Lib . cl_Lib . lib_NegSize) + (cb -> cb_Lib . cl_Lib . lib_PosSize)) );
}
return( (LONG)seg );
}